﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Remoting;
using System.Management.Automation.Runspaces;
using System.Security;
using System.Text;
using LiveatEdu.model;


namespace LiveatEdu.dao
{
    class ConnectionPS

    {
        private PowerShell ps;
        private string username;
        private SecureString password;
        private ConnectionTXT logSystem;

        public bool CreatePerson(Person person)
        {
            Command command = new Command("new-mailbox");
            command.Parameters.Add("Name", person.Cn);
            command.Parameters.Add("Password", person.Password);
            command.Parameters.Add("WindowsLiveID", person.Mail);
            command.Parameters.Add("ResetPasswordOnNextLogon", 1);
            command.Parameters.Add("FirstName", person.GivenName);
            command.Parameters.Add("LastName", person.Sn);
            command.Parameters.Add("DisplayName", person.Cn);
            Pipeline pipeline = this.ps.Runspace.CreatePipeline();
            pipeline.Commands.Add(command);
            try
            {
                Collection<PSObject> results = pipeline.Invoke();
                if (pipeline.Error.Count > 0)
                {
                    var error = pipeline.Error.Read() as Collection<ErrorRecord>;
                    if (error != null)
                    {
                        foreach (ErrorRecord er in error)
                        {
                            ConsoleLiveEdu.logFile.AddMSgError("[PowerShell]: erro ao criar usuário: " + person.Mail + " já existe");
                            Console.WriteLine("[PowerShell]: erro ao criar usuário: " + person.Mail + " já existe");
                             return false;
                        }
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ConsoleLiveEdu.logFile.AddMSgError(ex.Message);
                return false;
            }
        }

        public bool CreateGroup(Group group)
        {
            Command command = new Command("New-DistributionGroup");
            command.Parameters.Add("Name", group.Name);
            command.Parameters.Add("Alias", group.Alias);
            command.Parameters.Add("PrimarySmtpAddress", group.PrimaySmtpAddress);
            command.Parameters.Add("ModerationEnabled", true);
            command.Parameters.Add("ModeratedBy", group.ManagedBy);
            command.Parameters.Add("Notes", group.Notes);
            command.Parameters.Add("Type", "Security");
            Pipeline pipeline = this.ps.Runspace.CreatePipeline();
            pipeline.Commands.Add(command);
            try
            {
                Collection<PSObject> results = pipeline.Invoke();
                if (pipeline.Error.Count > 0)
                {
                    var error = pipeline.Error.Read() as Collection<ErrorRecord>;
                    if (error != null)
                    {
                        foreach (ErrorRecord er in error)
                        {
                            ConsoleLiveEdu.logFile.AddMSgError("[PowerShell]: Erro ao criar grupo: " + er.Exception.Message);
                            Console.WriteLine("[PowerShell]: Erro ao criar grupo: " + er.Exception.Message);
                            return false;
                        }
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ConsoleLiveEdu.logFile.AddMSgError(ex.Message);
                return false;
            }
        }

        public bool AddUserDistributionGroup(Lession lession)
        {
            Command command = new Command("Add-DistributionGroupMember");
            command.Parameters.Add("Identity", lession.Gd);
            command.Parameters.Add("Member", lession.Name);

            Pipeline pipeline = this.ps.Runspace.CreatePipeline();
            pipeline.Commands.Add(command);
            try
            {
                Collection<PSObject> results = pipeline.Invoke();
                if (pipeline.Error.Count > 0)
                {
                    var error = pipeline.Error.Read() as Collection<ErrorRecord>;
                    if (error != null)
                    {
                        foreach (ErrorRecord er in error)
                        {
                            ConsoleLiveEdu.logFile.AddMSgError("[PowerShell]: Erro ao adicionar usuário em grupo: " + er.Exception.Message);
                            Console.WriteLine("[PowerShell]: Erro ao adicionar usuário em grupo: " + er.Exception.Message);
                            return false;
                        }
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ConsoleLiveEdu.logFile.AddMSgError(ex.Message);
                return false;
            }            
        }

        public List<String> GetAllMailbox()
        {
            List<String> mailboxList = new List<String>(); 
            Command command = new Command("Get-Mailbox");
            command.Parameters.Add("ResultSize", "unlimited");
            command.Parameters.Add("SortBy", "Alias");
            Pipeline pipeline = this.ps.Runspace.CreatePipeline();
            pipeline.Commands.Add(command);
            try
            {
                Collection<PSObject> results = pipeline.Invoke();
                for (int i = 0; i < results.Count; i++)
                { 
                mailboxList.Add(Convert.ToString(results[i].Members.ElementAt(162).Value));
                }
                
                if (pipeline.Error.Count > 0)
                {
                    var error = pipeline.Error.Read() as Collection<ErrorRecord>;
                    if (error != null)
                    {
                        foreach (ErrorRecord er in error)
                        {
                            ConsoleLiveEdu.logFile.AddMSgError("[PowerShell]: Erro ao gerar lista de caixas de correio de usuários: " + er.Exception.Message);
                            Console.WriteLine("[PowerShell]: Erro ao gerar lista de caixas de correio de usuários: " + er.Exception.Message);
                            return null;
                        }
                    }
                }
                return mailboxList;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ConsoleLiveEdu.logFile.AddMSgError(ex.Message);
                return null;
            }            
        }

        public List<String> GetAllDistributionGroup()
        {
            List<String> distributionGroupList = new List<String>();
            Command command = new Command("Get-DistributionGroup");
            command.Parameters.Add("ResultSize", "unlimited");
            Pipeline pipeline = this.ps.Runspace.CreatePipeline();
            pipeline.Commands.Add(command);
            try
            {
                Collection<PSObject> results = pipeline.Invoke();
                for (int i = 0; i < results.Count; i++)
                {
                    distributionGroupList.Add(Convert.ToString(results[i].Members.ElementAt(53).Value));
                }

                if (pipeline.Error.Count > 0)
                {
                    var error = pipeline.Error.Read() as Collection<ErrorRecord>;
                    if (error != null)
                    {
                        foreach (ErrorRecord er in error)
                        {
                            ConsoleLiveEdu.logFile.AddMSgError("[PowerShell]: Erro ao ler grupos de distribuição: " + er.Exception.Message);
                            Console.WriteLine("[PowerShell]: Erro ao ler grupos de distribuição: " + er.Exception.Message);
                            return null;
                        }
                    }
                }
                return distributionGroupList;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ConsoleLiveEdu.logFile.AddMSgError(ex.Message);
                return null;
            }
        }

        public bool DisablePOP(Person person)
        { 
            Command command = new Command("Set-CASMailbox");
            command.Parameters.Add("Identity", person.Mail);
            command.Parameters.Add("PopEnabled", false);
            Pipeline pipeline = this.ps.Runspace.CreatePipeline();
            pipeline.Commands.Add(command);
            try
            {
                Collection<PSObject> results = pipeline.Invoke();
                if (pipeline.Error.Count > 0)
                {
                    var error = pipeline.Error.Read() as Collection<ErrorRecord>;
                    if (error != null)
                    {
                        foreach (ErrorRecord er in error)
                        {
                            ConsoleLiveEdu.logFile.AddMSgError("[PowerShell]: erro ao desabilitar POP do usuário: " + person.Mail + " já existe");
                            Console.WriteLine("[PowerShell]: erro ao desabilitar POP do usuário: " +person.Mail +" já existe");
                            return false;
                        }
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ConsoleLiveEdu.logFile.AddMSgError(ex.Message);
                return false;
            }
        }

        public ConnectionPS(string username, SecureString password)
        {
            this.username = username;
            this.password = password;
            this.ps = PowerShell.Create();
            this.logSystem = new ConnectionTXT();
            this.ps.Runspace = this.Conection(this.username,this.password);
        }

        public Runspace Conection(string userName, SecureString password)
        {
            try
            {
                PSCredential credential = new PSCredential(userName, password);
                WSManConnectionInfo connectionInfo = new WSManConnectionInfo(
                    new Uri("https://ps.outlook.com/powershell"),
                    "http://schemas.microsoft.com/powershell/Microsoft.Exchange",
                    credential);
                connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Basic;
                connectionInfo.MaximumConnectionRedirectionCount = 2;
                Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo);
                runspace.Open();
                ConsoleLiveEdu.logFile.AddMSgError("Runspace  successful open at " + DateTime.Now);
                return runspace;
            }
            catch (PSRemotingTransportException e)
            {
                Console.WriteLine(e);
                ConsoleLiveEdu.logFile.AddMSgError("Não foi possível abrir a conexão com o outlook Live, verifique sua conexão");
                Console.WriteLine("Não foi possível abrir a conexão com o outlook Live, verifique sua conexão");
                return null;
            }
        }

        public void Close()
        {

            this.ps.Runspace.Close();
            ConsoleLiveEdu.logFile.AddMSgError("Runspace  successful close at " + DateTime.Now);
        }
    }
}